﻿using Coder.Configs;
using Egg;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Coder.Entity
{
    public class EntityDataPlug : IDataPlug
    {
        // 获取类型的默认值
        private string GetDefaultValue(string typeName)
        {
            switch (typeName)
            {
                case "string": return "string.Empty";
                case "byte":
                case "short":
                case "int":
                case "long":
                case "ushort":
                case "uint":
                case "ulong":
                case "float":
                case "double":
                case "decimal":
                    return "0";
                case "bool":
                    return "false";
                case "DateTime": return "DateTime.Now";
                default: return string.Empty;
            }
        }

        private string Space(int len) { return new string(' ', len); }

        private string GetCSharpClassCode(Table table)
        {
            StringBuilder sb = new StringBuilder();
            var space2 = new string(' ', 8);
            string tabSchema = table.Properties.Schema;
            string tabInherit = "";
            if (table.Properties.ContainsKey("Inherit")) tabInherit = ": " + table.Properties.Inherit;
            string tabName = table.Properties.VarName;
            string tabDbName = table.Properties.DbName;
            string tabText = table.Properties.Text;
            //sb.AppendLine();
            for (int i = 0; i < table.Columns.Count; i++)
            {
                var col = table.Columns[i];
                if (col.IsBuild)
                {
                    //var colType = _setting.ColumnTypes.Where(d => d.Name == col.ColumnType).FirstOrDefault();
                    var colTypeCSharp = col.VarType;
                    if (string.IsNullOrWhiteSpace(colTypeCSharp)) colTypeCSharp = "string";
                    if (col.IsNullable && colTypeCSharp != "string")
                    {
                        colTypeCSharp += "?";
                    }
                    if (sb.Length > 0)
                    {
                        sb.AppendLine($"{space2}/// <summary>");
                    }
                    else
                    {
                        sb.AppendLine($"/// <summary>");
                    }

                    sb.AppendLine($"{space2}/// {col.Text}");
                    sb.AppendLine($"{space2}/// </summary>");
                    switch (col.DbType)
                    {
                        case "varchar":
                            if (col.DbTypeLength > 0)
                            {
                                sb.AppendLine($"{space2}[Column(\"{col.DbName}\", TypeName = \"{col.DbType}({col.DbTypeLength})\")]");
                                sb.AppendLine($"{space2}[StringLength({col.DbTypeLength})]");
                            }
                            else
                            {
                                sb.AppendLine($"{space2}[Column(\"{col.DbName}\", TypeName = \"{col.DbType}\")]");
                            }
                            break;
                        case "decimal":
                            sb.AppendLine($"{space2}[Column(\"{col.DbName}\", TypeName = \"{col.DbType}({col.DbTypeLength},{col.DbTypeFloat})\")]");
                            break;
                        default:
                            sb.AppendLine($"{space2}[Column(\"{col.DbName}\", TypeName = \"{col.DbType}\")]");
                            break;
                    }
                    sb.AppendLine($"{space2}[Description(\"{col.Text}\")]");
                    sb.Append($"{space2}public virtual {colTypeCSharp} {col.VarName} {{ get; set; }}");
                    // 根据是否为空填充默认数据
                    if (!col.IsNullable)
                    {
                        string defaultValue = GetDefaultValue(colTypeCSharp);
                        if (!defaultValue.IsEmpty())
                        {
                            sb.Append($" = {defaultValue};");
                        }
                    }
                    sb.AppendLine();
                }
            }
            return sb.ToString();
        }

        private string GetCSharpDtoCode(Table table)
        {
            StringBuilder sb = new StringBuilder();
            string tabSchema = table.Properties.Schema;
            string tabInherit = "";
            if (table.Properties.ContainsKey("Inherit")) tabInherit = ": " + table.Properties.Inherit;
            string tabName = table.Properties.DbName;
            string tabText = table.Properties.Text;
            for (int i = 0; i < table.Columns.Count; i++)
            {
                var col = table.Columns[i];
                if (col.IsBuild)
                {
                    var colTypeCSharp = col.VarType;
                    if (string.IsNullOrWhiteSpace(colTypeCSharp)) colTypeCSharp = "string";
                    if (col.IsNullable && colTypeCSharp != "string")
                    {
                        colTypeCSharp += "?";
                    }
                    if (sb.Length > 0)
                    {
                        sb.AppendLine($"{Space(8)}/// <summary>");
                    }
                    else
                    {
                        sb.AppendLine($"/// <summary>");
                    }
                    //sb.AppendLine($"{Space(4)}/// <summary>");
                    sb.AppendLine($"{Space(8)}/// {col.Text}");
                    sb.AppendLine($"{Space(8)}/// </summary>");
                    //if (col.IsRequired) sb.AppendLine($"{Space(8)}[Required]");
                    sb.Append($"{Space(8)}public virtual {colTypeCSharp} {col.VarName} {{ get; set; }}");
                    // 根据是否为空填充默认数据
                    if (!col.IsNullable)
                    {
                        string defaultValue = GetDefaultValue(colTypeCSharp);
                        if (!defaultValue.IsEmpty())
                        {
                            sb.Append($" = {defaultValue};");
                        }
                    }
                    sb.AppendLine();
                }
            }
            return sb.ToString();
        }

        // 获取出参代码
        private string GetCSharpInputParams(Table table)
        {
            StringBuilder sb = new StringBuilder();
            string tabSchema = table.Properties.Schema;
            string tabInherit = "";
            if (table.Properties.ContainsKey("Inherit")) tabInherit = ": " + table.Properties.Inherit;
            string tabName = table.Properties.DbName;
            string tabText = table.Properties.Text;
            for (int i = 0; i < table.Columns.Count; i++)
            {
                var col = table.Columns[i];
                if (col.IsBuild)
                {
                    var colTypeCSharp = col.VarType;
                    if (string.IsNullOrWhiteSpace(colTypeCSharp)) colTypeCSharp = "string";
                    if (col.IsNullable && colTypeCSharp != "string")
                    {
                        colTypeCSharp += "?";
                    }
                    if (sb.Length > 0)
                    {
                        sb.AppendLine($"{Space(8)}/// <summary>");
                    }
                    else
                    {
                        sb.AppendLine($"/// <summary>");
                    }
                    //sb.AppendLine($"{Space(4)}/// <summary>");
                    sb.AppendLine($"{Space(8)}/// {col.Text}");
                    sb.AppendLine($"{Space(8)}/// </summary>");
                    if (col.IsRequired) sb.AppendLine($"{Space(8)}[Required]");
                    sb.Append($"{Space(8)}public virtual {colTypeCSharp} {col.VarName} {{ get; set; }}");
                    // 根据是否为空填充默认数据
                    if (!col.IsNullable)
                    {
                        string defaultValue = GetDefaultValue(colTypeCSharp);
                        if (!defaultValue.IsEmpty())
                        {
                            sb.Append($" = {defaultValue};");
                        }
                    }
                    sb.AppendLine();
                }
            }
            return sb.ToString();
        }

        // 获取出参代码
        private string GetCSharpUpdateProperties(Table table)
        {
            StringBuilder sb = new StringBuilder();
            string tabSchema = table.Properties.Schema;
            string tabInherit = "";
            if (table.Properties.ContainsKey("Inherit")) tabInherit = ": " + table.Properties.Inherit;
            string tabName = table.Properties.DbName;
            string tabText = table.Properties.Text;
            for (int i = 0; i < table.Columns.Count; i++)
            {
                var col = table.Columns[i];
                if (col.IsBuild)
                {
                    var colTypeCSharp = col.VarType;
                    if (string.IsNullOrWhiteSpace(colTypeCSharp)) colTypeCSharp = "string";
                    if (col.IsNullable && colTypeCSharp != "string")
                    {
                        colTypeCSharp += "?";
                    }
                    if (sb.Length > 0)
                    {
                        sb.AppendLine();
                        sb.Append($"{Space(12)}info.{col.VarName} = {col.VarName};");
                    }
                    else
                    {
                        sb.Append($"info.{col.VarName} = {col.VarName};");
                    }
                }
            }
            return sb.ToString();
        }

        // 获取查询属性
        private string GetCSharpSelectProperties(Table table)
        {
            StringBuilder sb = new StringBuilder();
            string tabSchema = table.Properties.Schema;
            string tabAbbr = table.Properties.Abbr;
            string tabInherit = "";
            if (table.Properties.ContainsKey("Inherit")) tabInherit = ": " + table.Properties.Inherit;
            string tabName = table.Properties.DbName;
            string tabText = table.Properties.Text;
            for (int i = 0; i < table.Columns.Count; i++)
            {
                var col = table.Columns[i];
                if (col.IsBuild)
                {
                    if (sb.Length > 0)
                    {
                        sb.AppendLine();
                        sb.Append($"{Space(16)}{col.VarName} = {tabAbbr}.{col.VarName},");
                    }
                    else
                    {
                        sb.Append($"{col.VarName} = {tabAbbr}.{col.VarName},");
                    }
                }
            }
            return sb.ToString();
        }

        public void Execute(ModuleConfig config, string name)
        {
            //throw new NotImplementedException();
            var data = config.Data;
            var dataProject = data[name];
            //SystemOpreator.Set("SourcePath", sourcePath);
            //SystemOpreator.Set("SettingPath", pathSetting);
            //SystemOpreator.Set("TargetPath", targetPath);
            var pathWork = SystemOpreator.GetContent("WorkPath");
            var pathSource = SystemOpreator.GetContent("SourcePath");
            var pathSetting = SystemOpreator.GetContent("SettingPath");
            var pathTarget = SystemOpreator.GetContent("TargetPath");
            var pathDefine = pathWork + "entities/" + dataProject["DefinePath"];
            string json = egg.IO.ReadUtf8FileContent(pathDefine);
            Table table = JsonSerializer.Deserialize<Table>(json) ?? new Table();
            dataProject["CSharpClassCode"] = GetCSharpClassCode(table);
            dataProject["CSharpDtoCode"] = GetCSharpDtoCode(table);
            dataProject["CSharpInputParams"] = GetCSharpInputParams(table);
            dataProject["CSharpUpdateProperties"] = GetCSharpUpdateProperties(table);
            dataProject["CSharpInherit"] = table.Properties.Inherit;
            dataProject["CSharpSelectProperties"] = GetCSharpSelectProperties(table);
        }
    }
}
